﻿using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace AgFractal.Coloring
{
    public class Gradient
    {
        public event EventHandler GradientChanged;

        private List<ColorEntry> _Entries;
        public List<ColorEntry> Entries
        {
            get
            {
                return _Entries;
            }
            set
            {
                _Entries = value;
                CalcColors();
            }
        }

        internal void CalcColors()
        {
            Colors = CalcGradient();
            if (GradientChanged != null)
                GradientChanged(this, null);
        }

        public List<Color> Colors { get; private set; }

        public Gradient()
        {
            Entries = new List<ColorEntry>();
        }

        public Gradient Clone()
        {
            return new Gradient { Entries = _Entries.ToList() };
        }

        List<Color> CalcGradient()
        {
            var sorted = Entries.OrderBy(i => i.Idx).ToList();
            var result = new List<Color>();
            for (int i = 0; i < sorted.Count - 1; i++)
            {
                if (i > 0)
                    result.RemoveAt(result.Count - 1);
                foreach (var color in CalcGradient(sorted[i].Color,
                    sorted[i + 1].Color, sorted[i + 1].Idx - sorted[i].Idx + 1))
                    result.Add(color);
            }
            return result;
        }

        static List<Color> CalcGradient(Color c1, Color c2, int steps)
        {
            double sr = (double)(c2.R - c1.R) / (steps - 1);
            double sg = (double)(c2.G - c1.G) / (steps - 1);
            double sb = (double)(c2.B - c1.B) / (steps - 1);

            var result = new List<Color>();
            for (int i = 0; i < steps; i++)
            {
                result.Add(Color.FromArgb(255,
                   (byte)(c1.R + sr * i),
                   (byte)(c1.G + sg * i),
                   (byte)(c1.B + sb * i)));
            }
            return result;
        }
    }
}